/**
 *  Copyright (c) 2010-2011, Monash e-Research Centre
 * (Monash University, Australia)
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 * * Neither the name of the Monash University nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
package edu.monash.historyofadoption;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.xmlrpc.XmlRpcException;

import quicktime.streaming.NewPresentationParams;

import arc.xml.XmlDoc;

/**
 * Servlet implementation class Submit
 */
public class ListAssets extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ListAssets() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// put the form here? or look up how to do JSP
		// what's JSP :P
		PrintWriter out = response.getWriter();
		try {
			out.println(ListAssets.htmlheader);

			// out.println("Hello World");
			String domain = request.getParameter("domain");
			String user = request.getParameter("user");
			String password = request.getParameter("password");

			InputStream inputStream = ListAssets.class.getClassLoader()
					.getResourceAsStream("setup.properties");

			Properties properties = new Properties();

			// load the inputStream using the Properties
			properties.load(inputStream);
			// get the value of the property
			String host = properties.getProperty("mediaflux.server.host");
			int port = Integer.parseInt(properties
					.getProperty("mediaflux.server.port"));
			String basecollection = properties
					.getProperty("mediaflux.server.basecollection");
			Boolean useSSL = Boolean.valueOf(properties
					.getProperty("mediaflux.server.useSSL"));
			Boolean encrypt = Boolean.valueOf(properties
					.getProperty("mediaflux.server.encrypt"));

			MediafluxConfig mfConfig = new MediafluxConfig(host, port, domain,
					user, password, useSSL, encrypt, basecollection);

			MediafluxClient myMFClient;
			HashMap newPage = null;
			try {
				myMFClient = new MediafluxClient(mfConfig);

				Boolean uploading = false;

				if (request.getParameter("submit") != null) {
					String mode = request.getParameter("submit");
					uploading = mode.equals("Upload to Confluence");
				}
				// files not uploaded anymore
				Boolean successful = false;
				Boolean loginError = false;
				String[] assets = null;
				if (uploading) {
					assets = request.getParameterValues("assets");
					// out.println(assets);
					// test confluence
					String confluence_user = request
							.getParameter("confluence_user");
					String confluence_pw = request
							.getParameter("confluence_pw");
					try {
						ConfluenceUploader myUploader = new ConfluenceUploader(
								confluence_user, confluence_pw);

						newPage = myUploader.createPage(request
								.getParameter("title"), request
								.getParameter("abstract"), confluence_user);

						Collection<XmlDoc.Element> uploadassetlist = myMFClient
								.getAssetList(request.getParameter("namespace"));

						Iterator<XmlDoc.Element> upit = uploadassetlist
								.iterator();
						while (upit.hasNext()) {
							String assetId = null;
							String contentType = null;
							String comment = null;
							XmlDoc.Element e = (XmlDoc.Element) upit.next();
							assetId = myMFClient.getAssetId(e);
							String assetName = myMFClient.getAssetName(e);

							if (assets != null) if (Arrays.asList(assets).contains(assetId)) {

								byte[] data = myMFClient.getAssetContents(
										assetId).bytearray();

								contentType = myMFClient.getAssetType(e);
								// contentType = myMFClient.getAssetContents(
								// assetId).type();
								comment = " ";
								myUploader.attachStuff((String) newPage
										.get("id"), assetName, contentType,
										comment, data);
							} else if (assetName != null) if (assetName.equals("metadata.txt")) {
								byte[] data = myMFClient.getAssetContents(
										assetId).bytearray();
								comment = "MODS Metadata";
								String dccomment = "Dublin core metadata";
								contentType = "text/xml";
								// read in xml template
								InputStream modsTemplateIS = ListAssets.class
										.getClassLoader().getResourceAsStream(
												"hoa-mods-template.xml.txt");
								InputStream dcTemplateIS = ListAssets.class
										.getClassLoader()
										.getResourceAsStream(
												"hoa-dc-template_steveedit.xml.txt");

								BufferedReader br = new BufferedReader(
										new InputStreamReader(modsTemplateIS));
								BufferedReader dcbr = new BufferedReader(
										new InputStreamReader(dcTemplateIS));
								String line;
								StringBuffer result = new StringBuffer();
								while ((line = br.readLine()) != null) {
									result.append(line + "\n");
								}
								String xml = result.toString();

								line = null;
								result = new StringBuffer();
								while ((line = dcbr.readLine()) != null) {
									result.append(line + "\n");
								}
								String dc = result.toString();
								// out.println(dc);
								// out.println("lalalal");
								// read in metadata.txt

								String metadata = new String(data);
								HashMap<String, String> pars = convertMetadataTxt(metadata);

								String fullname = "anonymous";
								String surname = "anonymous";
								String firstname = "anonymous";
								if (pars.get("publicly_linked").trim().equals(
										"yes")) {
									surname = pars.get("participant_surname");
									firstname = pars.get("participant_name");
									fullname = surname + ", " + firstname;
								}
								dc = dc.replaceFirst("___title___", request
										.getParameter("title"));
								dc = dc.replaceFirst("___fullname___", fullname);
								dc = dc.replaceFirst("___researcher_name___",
										"Quartly, Marian");

								dc = dc.replaceFirst("___experience___", pars
										.get("experience"));
								xml = xml.replaceAll("___experience___", pars
										.get("experience"));

								xml = xml.replaceFirst("___title___", request
										.getParameter("title"));
								xml = xml.replaceFirst("___family___", surname);
								xml = xml
										.replaceFirst("___given___", firstname);
								xml = xml.replaceFirst("___roleterm___", "creator");
								// what
								// roleterm is
								String geostring = "";
								if (pars.containsKey("adoption_region"))
									if (!pars.get("adoption_region").trim()
											.equals("")) {
										if (!geostring.equals(""))
											geostring = geostring + ", ";
										if (pars.get("adoption_region").equals("Metropolitan"))
											geostring = geostring + "Metropolitan Australia";
										else if (pars.get("adoption_region").equals("Regional"))
											geostring = geostring + "Regional Australia";
									}
								if (pars.containsKey("adoption_state"))
									if (!pars.get("adoption_state").trim()
											.equals("")) {
										if (pars.get("adoption_state").trim()
												.equals("other")
												&& !pars.get("adoption_place")
														.trim().equals("")) {
											geostring = geostring
													+ pars
															.get("adoption_place");
										}
										if (!geostring.equals(""))
											geostring = geostring + ", ";
										geostring = geostring
												+ pars.get("adoption_state");
									}
								if (!geostring.equals("")) {
									xml = xml
											.replaceFirst(
													"___geographic___",
													"		<!-- geographic or chronological coverage; include region, decade, date, place-->\n"
															+ "		<mods:subject authority=\"local\">\n"
															+ "			<mods:geographic>"
															+ geostring
															+ "</mods:geographic>\n"
															+ "		</mods:subject>");
									dc = dc
											.replaceFirst(
													"___geographic___",
													"	<!-- geographic or chronological coverage;"
															+ " include region, decade, date, place-->\n"
															+ "	<dc:coverage>"
															+ geostring
															+ "</dc:coverage>");
								} else {
									xml = xml.replaceFirst("___geographic___",
											"");
									dc = dc
											.replaceFirst("___geographic___",
													"");
								}
								if (!pars.get("date_adoption").trim()
										.equals("")) {
									xml = xml.replaceFirst("___temporal___",
											"		<mods:subject authority=\"local\">\n"
													+ "			<mods:temporal>"
													+ pars.get("date_adoption")
													+ "</mods:temporal>\n"
													+ "		</mods:subject>\n");
									dc = dc
											.replaceFirst(
													"___temporal___",
													"	<!-- geographic or chronological coverage; "
															+ "include region, decade, date, place-->\n"
															+ "	<dc:coverage>"
															+ pars
																	.get("date_adoption")
															+ "</dc:coverage>");
								} else {
									xml = xml
											.replaceFirst("___temporal___", "");
									dc = dc.replaceFirst("___temporal___", "");
								}
								xml = xml.replaceFirst(
										"___researcher_lastname___", "Quartly");
								xml = xml.replaceFirst(
										"___researcher_firstname___", "Marian");
								//xml = xml.replaceFirst("___identifier___",
									//	assetId); // TO DONE: not sure
								// where the
								// identifier lives

								data = xml.getBytes();
								byte[] dcdata = dc.getBytes();

								assetName = "MODS.xml";
								String dcAssetName = "dc.xml";
								myUploader.attachStuff((String) newPage
										.get("id"), assetName, contentType,
										comment, data);
								myUploader.attachStuff((String) newPage
										.get("id"), dcAssetName, contentType,
										dccomment, dcdata);
								String labels = "";
								if (pars.get("date_adoption") != null) 
									labels += pars.get("date_adoption").replace(" ", "").trim().toLowerCase() + " ";
								if (pars.get("experience") != null) 
									labels += pars.get("experience").replace(" ", "").trim().toLowerCase() + " ";
								if (pars.get("adoption_region") != null) 
									labels += pars.get("adoption_region").replace(" ", "").trim().toLowerCase()	+ " ";
								if (pars.get("adoption_state") != null) if (pars.get("adoption_state").replace(" ", "")
										.trim().toLowerCase().equals("other")) {
									labels += pars.get("adoption_place")
											.replace(" ", "").trim()
											.toLowerCase();
								} else {
									labels += pars.get("adoption_state")
											.replace(" ", "").trim()
											.toLowerCase();
								}
								myUploader.addLabelToPage(newPage.get("id"),
										labels);
							}

						}

						successful = true;
					} catch (XmlRpcException e) {
						e.printStackTrace();
						out.println(e.getMessage());
						if (e.getMessage().contains(
								"AuthenticationFailedException")) {
							loginError = true;
						}
						successful = false;
					}

				}

				if (!successful) {

					if (uploading == true && loginError == false) {
						out
								.println("<h3 style='color:red;'>Page creation failed.</h3>");
						out
								.println("<p style='color:red;'>This could be either because you used a page title that already exists, or due to some other error<br/>");
						out
								.println("Please contact the system administrator if problem persists</p>");
					}
					out
							.println("<h2>Enter details and choose files to submit</h2>");

					// "Go back" form-button BEGIN
					out.println("<form action='submit' method=POST>");
					out.println("<input type='hidden' name='domain' value='"
							+ domain + "' />");
					out.println("<input type='hidden' name='user' value='"
							+ user + "' />");
					out.println("<input type='hidden' name='password' value='"
							+ password + "' />");
					out.println("<input type=\"submit\" ");
					out
							.println("value='go back to Collection choice' /></form>");
					// "Go back" form-button END

					// RETRIEVE FORM POST VARS
					// String domain = "mflux-dev";
					// String user = "stevea";
					// String password = "mfluxd3v";

					out.println("<form action=\"listAssets\" method=POST>");
					out.println("<input type='hidden' name='domain' value='"
							+ domain + "' />");
					out.println("<input type='hidden' name='user' value='"
							+ user + "' />");
					out.println("<input type='hidden' name='password' value='"
							+ password + "' />");
					out.print("<p><input type='text' name='title' value='");
					if (uploading)
						out.print(request.getParameter("title"));
					else
						out.print("Title");
					out.println("' size='50' /><br/>");
					out.print("<textarea name='abstract' cols='80' rows='5'>");
					if (uploading)
						out.print(request.getParameter("abstract"));
					else
						out.print("Enter Abstract here... ");
					out.println("</textarea></p>");

					// out.println("<p>Should the story teller's name be public or anonymous?<br/>");
					// out.println("<input type='radio' name='anonymity' value='public' />Public<br/>");
					// out.println("<input type='radio' name='anonymity' value='anonymous' />Anonymous</p>");

					out.println("Collections under: "
							+ mfConfig.getBasecollection());

					String namespace = request.getParameter("namespace");
					out.println("<input type='hidden' name='namespace' value='"
							+ namespace + "' />");
					// out.println("<p>Collection name: <a href=\"listAssets?name="+namespace+"\">"
					// + namespace + "</a>");
					// out.println("####<br/>");

					Collection<XmlDoc.Element> assetlist = myMFClient
							.getAssetList(namespace);

					Iterator<XmlDoc.Element> it = assetlist.iterator();
					out.println("<p>");
					while (it.hasNext()) {
						XmlDoc.Element e = (XmlDoc.Element) it.next();
						String assetName = myMFClient.getAssetName(e);
						if (assetName == null)
							continue;
						if (!assetName.equals("metadata.txt")) {
							String assetId = myMFClient.getAssetId(e);
							// out.println(assets);
							out.print("<input type='checkbox' name='assets' ");
							if (uploading
									&& Arrays.asList(assets).contains(assetId))
								out.print("checked");
							out.println(" value='" + assetId + "'>" + assetName
									+ " (type: " + myMFClient.getAssetType(e)
									+ ")<br/>");
							// displayAssetContentInfo(getAssetContents(getAssetId(e)),
							// out);
							// out.println("</li>");
						}
					}
					out.println("</p>");

					out.println("<h3>Confluence Login Details</h3>");
					if (uploading == true && loginError == true) {
						out
								.println("<h3 style='color:red;'>Login failed. Please check your login details</h3>");
					}
					out
							.println("<p>Username: <input type='text' name='confluence_user' size=30 /><br />");
					out
							.println("Password: <input type='password' name='confluence_pw' size=30 /></p>");

					out.println("<input type='hidden' name='namespace' value='"
							+ request.getParameter("namespace") + "' />");
					out
							.println("<input type='submit' name='submit' value='Upload to Confluence' />");
					out.println("</form>");

				} else {
					out
							.println("<h2>Uploading was successful</h2><p>You can find your submission here: "
									+ "<a href='"
									+ newPage.get("url")
									+ "'>"
									+ newPage.get("url") + "</a>");
				}
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			out.println(ListAssets.htmlfooter);
			out.close();
		} catch (Throwable e) {
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/html");
			e.printStackTrace(printWriter);
			out
					.println("<strong>Oops!</strong><br/><br/>An error has occurred. Technical details are as follows:</br><br/><font face=\"Courier New\" size=\"2\">"
							+ stringWriter.toString() + "</font>");
		}
	}

	public static File createTempDirectory() throws IOException {
		final File temp;

		temp = File.createTempFile("temp", Long.toString(System.nanoTime()));

		if (!(temp.delete())) {
			throw new IOException("Could not delete temp file: "
					+ temp.getAbsolutePath());
		}

		if (!(temp.mkdir())) {
			throw new IOException("Could not create temp directory: "
					+ temp.getAbsolutePath());
		}

		return (temp);
	}

	private static HashMap<String, String> convertMetadataTxt(String input) {
		HashMap<String, String> output = new HashMap<String, String>();
		String[] parameters = input.split("param; name=");
		for (String string : parameters) {
			if (!string.trim().equals("")) {
				String[] par = string.split(", value=");
				output.put(par[0].trim(), par[1].trim());
			}
		}
		return output;
	}

	private static final String htmlheader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
			+ "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> "
			+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"de\" xml:lang=\"en\">"
			+ " <head>  <title>Submit story to Confluence</title>  "
			+ "<META name=\"robots\" content=\"noindex,nofollow\">"
			+ "<LINK href=\"static/form-style.css\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\">"
			+ "</head> "
			+ "<body>"
			+ "<DIV id=\"header\">"
			+ "<H1>History of Adoption in Australia</H1>"
			+ "<DIV id=\"logos\"><IMG src=\"static/logo-monash.jpg\" alt=\"Monash University logo\" "
			+ "name=\"logo_monash\" width=\"208\" height=\"34\" id=\"logo_monash\"><BR>"
			+ " <IMG src=\"static/acu-logo.jpg\" width=\"248\" height=\"35\" "
			+ "alt=\"Australian Catholic University logo\" id=\"logo_acu\"></DIV>"
			+ "<DIV class=\"clear_both\"></DIV>"
			+ "</DIV>"
			+ "<DIV id=\"content\"> ";
	private static final String htmlfooter = " </div> </body> </html> ";
}
